package util;

import RFID.rfid_def;
import RFID.rfidlib_AIP_ISO15693;
import RFID.rfidlib_aip_iso14443A;
import RFID.rfidlib_reader;
import com.dangdi.controller.websokectHandler;
import com.dangdi.dao.Dao;
import com.dangdi.service.ImportBookService;
import com.dangdi.sip2.SocketClientAct;
import com.dangdi.util.SocketClient2;
import com.dangdi.utils.SpringUtil;
import com.gexin.fastjson.JSON;
import org.apache.catalina.core.ApplicationContext;
import org.apache.http.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;

@Component
public class RfidReader implements Runnable {
    //最新
    private String comType;
    private String comName;
    private String reader_name;
    private String requestType;
    private String requestUrl;
    private String host;
    private int port;
    private int readCount;
    private int afi;
    private String rete;
    private SocketClient2 socketClient2;
    //结束
    private List<String> tagList = new ArrayList<>();
    private boolean flag = true;
    private int tagCount = -0;
    private long READER_HANDLER = 0;
    private int code = -1;
    private int code2 = 0;
    final String filePath = System.getProperty("user.dir") + "\\conf.properties";
    private PropertiesUtils utils = new PropertiesUtils(filePath);
    private String ip = null;
    private int actionType = 2;
    private int bookCount = 0;
    private Set<String> afiList = new HashSet();
    private List<String> tempList = new ArrayList<>();
    private String ImportBookTagUid = "";
    private String school = "";
    private String tag = "";
    private String cengRFID = "";

    private String socketHost;
    private int socketProt;


    //新

    public String getComType() {
        return comType;
    }

    public void setComType(String comType) {
        this.comType = comType;
    }

    public String getComName() {
        return comName;
    }

    public void setComName(String comName) {
        this.comName = comName;
    }

    public String getReader_name() {
        return reader_name;
    }

    public void setReader_name(String reader_name) {
        this.reader_name = reader_name;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getReadCount() {
        return readCount;
    }

    public void setReadCount(int readCount) {
        this.readCount = readCount;
    }

    public int getAfi() {
        return afi;
    }

    public void setAfi(int afi) {
        this.afi = afi;
    }

    public String getRete() {
        return rete;
    }

    public void setRete(String rete) {
        this.rete = rete;
    }

    public SocketClient2 getSocketClient2() {
        return socketClient2;
    }

    public void setSocketClient2(SocketClient2 socketClient2) {
        this.socketClient2 = socketClient2;
    }

    //结束

    public String getRequestUrl() {
        return requestUrl;
    }

    public void setRequestUrl(String requestUrl) {
        this.requestUrl = requestUrl;
    }

    public String getRequestType() {
        return requestType;
    }

    public void setRequestType(String requestType) {
        this.requestType = requestType;
    }

    public int getSocketProt() {
        return socketProt;
    }

    public void setSocketProt(int socketProt) {
        this.socketProt = socketProt;
    }

    public String getSocketHost() {
        return socketHost;
    }

    public void setSocketHost(String socketHost) {
        this.socketHost = socketHost;
    }

    ImportBookService service;

    public String getCengRFID() {
        return cengRFID;
    }

    public void setCengRFID(String cengRFID) {
        this.cengRFID = cengRFID;
    }

    public String getSchool() {
        return school;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;

    }

    public void setSchool(String school) {
        this.school = school;
    }

    websokectHandler sokect = new websokectHandler();

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    //改变状态不成功
    private Set<String> afiNotChangedList = new HashSet();

    public Set<String> getAfiNotChangedList() {
        return afiNotChangedList;
    }

    public void setAfiNotChangedList(Set<String> afiNotChangedList) {
        this.afiNotChangedList = afiNotChangedList;
    }

    public Set<String> getAfiList() {
        return afiList;
    }


    public int getActionType() {
        return actionType;
    }

    public void setActionType(int actionType) {
        this.actionType = actionType;
    }

    public void setAfiList(Set<String> afiList) {
        this.afiList = afiList;
    }

    public int getBookCount() {
        return bookCount;
    }

    public void setBookCount(int bookCount) {
        this.bookCount = bookCount;
    }


    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public int getCode2() {
        return code2;
    }

    public void setCode2(int code2) {
        this.code2 = code2;
    }

    public void run() {
        service = SpringUtil.getBean(ImportBookService.class);
        System.out.println("Service=" + service);
        setCode(-1);
        setCode2(-1);
        flag = false;
        int osType = 0;
        int arType = 0;
        String libPath = System.getProperty("user.dir");
        String osName = System.getProperty("os.name");
        String architecture = System.getProperty("os.arch");
        osName = osName.toUpperCase();
        if (osName.equals("LINUX")) {
            osType = rfid_def.VER_LINUX;
        } else if (osName.indexOf("WIN") != -1) {
            osType = rfid_def.VER_WINDOWS;
        }

        architecture = architecture.toUpperCase();
        if (architecture.equals("AMD64") || architecture.equals("X64") || architecture.equals("UNIVERSAL")) {
            arType = rfid_def.AR_X64;
        } else {
            arType = rfid_def.AR_X86;
        }

        rfidlib_reader.LoadLib(libPath, osType, arType);
        rfidlib_AIP_ISO15693.LoadLib(libPath, osType, arType);
        rfidlib_aip_iso14443A.LoadLib(libPath, osType, arType);
        System.out.println(libPath);
        int m_cnt = rfidlib_reader.RDR_GetLoadedReaderDriverCount();
        System.out.println("设备数量：" + m_cnt);
        int nret = 0;
        for (int i = 0; i < m_cnt; i++) {
            char[] valueBuffer = new char[256];
            Integer nSize = new Integer(0);
            String sDes;
            nret = rfidlib_reader.RDR_GetLoadedReaderDriverOpt(i,
                    rfid_def.LOADED_RDRDVR_OPT_CATALOG, valueBuffer, nSize);
            if (nret == 0) {
                sDes = String.copyValueOf(valueBuffer, 0, nSize);
                if (sDes.equals(rfid_def.RDRDVR_TYPE_READER)) {
                    rfidlib_reader.RDR_GetLoadedReaderDriverOpt(i, rfid_def.LOADED_RDRDVR_OPT_NAME, valueBuffer, nSize);
                    sDes = String.copyValueOf(valueBuffer, 0, nSize);
                    System.out.println(sDes);
                }
            }
        }
        if (m_cnt > 0) {
            System.out.println("驱动文件加载成功！");
        }
        String connstr1 = "";

        if (actionType == 3 || actionType == 4 || actionType == 6) {
            connstr1 = "RDType=RD201;CommType=COM;COMName=COM1;BaudRate=38400;Frame=8E1;BusAddr=255";
            connstr1 = "RDType=M201;CommType=COM;COMName=COM1;BaudRate=38400;Frame=8E1;BusAddr=255";
        } else {
            connstr1 = "RDType=M201;CommType=USB;AddrMode=0;SerNum=";

        }
        if (reader_name != null) {
            connstr1 = "RDType=" + reader_name + ";CommType=" + comType + ";COMName=" + comName + ";BaudRate=" + rete + ";Frame=8E1;BusAddr=255";

        }
        System.out.println("开启读卡器语句=" + connstr1);
        Long hrOut = new Long(0);
        int openStateCode = rfidlib_reader.RDR_Open(connstr1, hrOut);
        setCode(openStateCode);
        if (openStateCode != 0) {
            System.out.println("读卡器开启失败，错误代码：" + openStateCode);

            return;
        } else {
            System.out.println("设备开启成功!读卡器句柄为:" + hrOut);
            READER_HANDLER = hrOut;
        }
        char[] vbuf = new char[128];
        long status = 0;
        status = rfidlib_AIP_ISO15693.ISO15693_GetLibVersion(vbuf, 128);
        if (status != 0) {
            System.out.print("当前版本为：");
            System.out.println(vbuf);
        } else {
            System.out.println("读取版本信息失败");
        }
        long InvenParamSpecList = rfidlib_reader.RDR_CreateInvenParamSpecList();
        byte anntinaID = 0;
        byte en_afi = 0;
        byte Afi = 00;
        byte slot_type = 16;
        byte[] AntennaIDs = new byte[64];
        long Inventory = rfidlib_AIP_ISO15693.ISO15693_CreateInvenParam(InvenParamSpecList, anntinaID, en_afi, Afi, slot_type);
        long dnhReport = 0;
        String sUid = "";
        nret = rfidlib_reader.RDR_TagInventory(hrOut, (byte) 1, (byte) 0, AntennaIDs, InvenParamSpecList);
        tagList.clear();
        Integer aip_id = new Integer(0);
        Integer tag_id = new Integer(0);
        Integer ant_id = new Integer(0);
        Byte dsfid = new Byte((byte) 0);
        byte uid[] = new byte[8];
        flag = true;
        while (flag) {
            nret = rfidlib_reader.RDR_TagInventory(hrOut, (byte) 1, (byte) 0, AntennaIDs, InvenParamSpecList);
            tagCount = rfidlib_reader.RDR_GetTagDataReportCount(hrOut);
//             System.out.println("寻到的标签数:"+tagCount);
//            System.out.println(tagList.size());
            dnhReport = rfidlib_reader.RDR_GetTagDataReport(hrOut, (byte) 1);
            rfidlib_AIP_ISO15693.ISO15693_ParseTagDataReport(dnhReport, aip_id, tag_id, ant_id, dsfid, uid);
            boolean fal = false;
            if (dnhReport == 0 && tagList.size() != 0) {
                try {
                    clearTagList();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            bookCount = 0;
            afiList.clear();
            afiNotChangedList.clear();
            tempList.clear();
            while (dnhReport != 0) {
//            	try {
//					Thread.sleep(300);
//				} catch (InterruptedException e1) {
//					// TODO Auto-generated catch block
//					e1.printStackTrace();
//				}
                rfidlib_AIP_ISO15693.ISO15693_ParseTagDataReport(dnhReport, aip_id, tag_id, ant_id, dsfid, uid);
                sUid = gFunction.encodeHexStr(uid);
//                System.out.println(sUid);
                tempList.add(sUid);
                Long ht = new Long(0);
                byte[] m_uid = new byte[8];
                status = rfidlib_AIP_ISO15693.ISO15693_Connect(hrOut, 7, (byte) 1, uid, ht);
                if (status == 0) {
//                	System.out.println("连接标签成功");
//                	System.out.println("标签实例句柄为："+ht);


                } else {
                    System.out.println("连接标签失败");
                    System.out.println("错误代码=" + status);
                }
//                System.out.println("afi="+afi);
                if (actionType == 0 || afi == 0) {
                    int bb = 00;
                    byte bAfi = IntToByte(bb);
                    //改变AFI
                    status = rfidlib_AIP_ISO15693.ISO15693_WriteAFI(hrOut, ht, bAfi);
                    if (status == 0) {
                        bookCount++;
                        afiList.add(sUid);
//                        System.out.println(sUid+"=状态改成:"+bb);
//                     	System.out.println("写入AFI成功");
                    } else {
                        afiNotChangedList.add(sUid);
                        System.out.println("写入AFI失败");
                        System.out.println("错误代码=" + status);
                    }
                }

                if (actionType == 1 || actionType == 2 || afi == 1) {
                    int bb = 11;
                    byte bAfi = IntToByte(bb);
                    status = rfidlib_AIP_ISO15693.ISO15693_WriteAFI(hrOut, ht, bAfi);
                    if (status == 0) {
                        bookCount++;
                        afiList.add(sUid);
//                        System.out.println(sUid+"=状态改成:"+bb);
//                     	System.out.println("写入AFI成功");
                        if (actionType == 2) {
//                            System.out.println("读出来的id="+sUid);
                            if (!sUid.equals(ImportBookTagUid)) {
                                System.out.println("可以发websocketle");
                                Map<String, Object> map = new HashMap<String, Object>();
                                map.put("sUid", sUid);
                                map.put("from", "importBook");
                                sokect.onMessage(JSON.toJSONString(map));
                            }
                            ImportBookTagUid = sUid;
                        }
                    } else {
                        afiNotChangedList.add(sUid);
                        System.out.println("写入AFI失败");
                        System.out.println("错误代码=" + status);
                    }
                }

                if (actionType == 3) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("sUid", sUid);
                    map.put("from", "findingBookShelf");
                    sokect.onMessage(JSON.toJSONString(map));
                }
                if (actionType == 4) {
                    if (!sUid.equals(ImportBookTagUid)) {
                        Map<String, Object> map = new HashMap<String, Object>();
                        System.out.println("sUid=" + sUid);
                        System.out.println(service);
                        int row = service.checkBookShelfAndBook(sUid);
                        System.out.println(row);
                        if (row == 0) {
                            System.out.println(sUid);
                            System.out.println(school);
                            System.out.println(tag);
                            String bookCode = service.findBookBarCodeByBook_rfid(sUid);
                            System.out.println("查出来的条形码=" + bookCode);
                            row = service.insertBookShelfAndBook(school, tag, sUid, cengRFID, bookCode);
                            if (row == 1) {
                                map.put("sUid", sUid);
                                map.put("school", school);
                                map.put("cengRFID", cengRFID);
                                map.put("tag", tag);
                                map.put("bookName", service.findBookNameByBook_rfid(sUid));
                                map.put("bookCode", bookCode);
                                map.put("from", "findingBookShelfBookRfid");
                                map.put("code", 0);
                                map.put("msg", "已添加");
                            }
                        } else {
                            map.put("code", -1);
                            map.put("msg", "rfid重复被忽略");
                            System.out.println("书RFID重复已被忽略");
                        }
                        sokect.onMessage(JSON.toJSONString(map));
                    }
                    ImportBookTagUid = sUid;

                }
                if (actionType == 6) {
                    if (!sUid.equals(ImportBookTagUid)) {
                        Map<String, Object> map = new HashMap<String, Object>();
                        map = service.book_end_infoByRfid(sUid);
                        System.out.println("通过rfid查出来的map=" + map);
                        if (map != null) {
                            map.put("from", "PDC");
                            map.put("code", 0);
                            map.put("msg", "获取成功");
                        } else {
                            map.put("from", "PDC");
                            map.put("code", -1);
                            map.put("msg", "未查到信息");
                        }
                        sokect.onMessage(JSON.toJSONString(map));
                    }
                    ImportBookTagUid = sUid;
                }
                rfidlib_reader.RDR_TagDisconnect(hrOut, ht);

//                if (tagList.size()==0){
//                    try {
////                        System.out.println("即将添加List="+sUid);
//                        addTag(sUid);
////                        System.out.println("添加完了");
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    } catch (URISyntaxException e) {
//                        e.printStackTrace();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
                // tagCount 读卡器读出来的RFID的数量
                // tagList  rfid集合
                /*
                    tagList.size()=4;

                    tagCount=5;

                    if(tagCount>tagList.size()){
                        if(!checkList(sUid)){
                            addTag(sUid);
                        }

                    }else if(tagCount<tagList.size()){
                        if(!checkList(sUid)){
                            removeTag(sUid);
                        }
                    }

                 */
                //直接添加
//                if (!chickList(sUid)){
//                    try {
//                        addTag(sUid);
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    } catch (URISyntaxException e) {
//                        e.printStackTrace();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }

//                if (tagCount<tagList.size()){
//                    //         System.out.println("集合比目标大");
//                        try {
//                            tagList.clear();
//                            addTag(sUid);
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        } catch (URISyntaxException e) {
//                            e.printStackTrace();
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                }
//                else
//                    if (tagCount>tagList.size()){
//                    //       System.out.println("目标比集合大");
//                    if (!chickList(sUid)){
//                        try {
//                            addTag(sUid);
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        } catch (URISyntaxException e) {
//                            e.printStackTrace();
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                }
//                if (tagCount==tagList.size()&&tagCount!=0){
//                    if (!chickList(sUid)){
//                        try {
//                            removeTag(sUid);
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        } catch (URISyntaxException e) {
//                            e.printStackTrace();
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                }
                dnhReport = rfidlib_reader.RDR_GetTagDataReport(hrOut, (byte) 2);
            }
            if (!chickList(tempList)) {
//                System.out.println("两个集合不一样，清空掉tagList");
                tagList.clear();
//                System.out.println("tagList已被清空="+tagList);
                for (int i = 0; i < tempList.size(); i++) {
                    tagList.add(tempList.get(i));
                }
//                System.out.println("新的tagList已被赋值="+tagList);
                try {
//                    System.out.println("发送socket消息中....");
                    TagListListiner();
//                    System.out.println("已发送socket消息");
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
//                System.out.println("两个集合一样，不用发socket消息");
            }
//            System.out.println(tagList);
//            Reader thread = new Reader();
//            thread.ex=false;
//            System.out.println("readCount="+readCount);
            if (actionType == 0 || actionType == 3 || readCount == 0) {
                System.out.println(actionType);
                System.out.println(readCount);
                System.out.println("不等于2了,并且不等于-1了");
                flag = false;

            }

        }
        rfidlib_reader.DNODE_Destroy(InvenParamSpecList);
        rfidlib_reader.RDR_SetCommuImmeTimeout(READER_HANDLER);
        rfidlib_reader.RDR_DisconnectAllTags(hrOut);
        int closeCode = 0;
        rfidlib_reader.RDR_Close(READER_HANDLER);
        setCode2(closeCode);
    }


    private byte IntToByte(int n) {
        int m_tmp = n % 100;
        return (byte) (((m_tmp / 10) << 4) | (m_tmp % 10));
    }

    public void closeRfidDervice() {
        flag = false;
    }

    public boolean chickList(List<String> tList) {
//        int n=0;
//        for (int i=0;i<tagList.size();i++){
//            for (int k=0;k<tList.size();k++){
//                if (tagList.get(i).equals(tList.get(k))){
//                    n++;
//                }
//            }
//            System.out.println("n="+n);
//            System.out.println("i="+i);
//            if (n==i){
//                return false;
//            }
//        }
        if (tagList.size() == tList.size()) {
            return true;
        }
        return false;
    }

    public void addTag(String sUid) throws IOException, URISyntaxException, InterruptedException {
//           System.out.println("我要添加标签="+sUid);
        tagList.add(sUid);
//        System.out.println("我要添加标签2"+tagList);
        TagListListiner();
    }

    public void removeTag(String sUid) throws IOException, URISyntaxException, InterruptedException {
        //   System.out.println("我要删除标签，标签数："+tagList.size());
        if (tagList.size() == 0) {
            // System.out.println("最后一个也要删吗？");
        }
        tagList.remove(sUid);
        TagListListiner();

    }

    public void clearTagList() throws IOException, URISyntaxException, InterruptedException {
        tagList.clear();
        TagListListiner();
    }

    public void TagListListiner() throws IOException, URISyntaxException, InterruptedException {
//        System.out.println("requestType="+requestType);
//        System.out.println("host="+host);
//        System.out.println("port="+port);
//        System.out.println("requestUrl="+requestUrl);
        //Thread.currentThread().sleep(2000);
//        Thread.sleep(Long.parseLong("1000"));
//        System.out.println("这是监听标签的方法");
        HttpClientUtil httpClientUtil = new HttpClientUtil();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("data_rfid", tagList);
        String filePath = System.getProperty("user.dir") + "\\conf.properties";
        //定义修改配置文件的工具类
        PropertiesUtils utils = new PropertiesUtils(filePath);
        map.put("machine_type", utils.getKeyValue("terminalSymbol"));
        map.put("terminalNumber", utils.getKeyValue("terminalNumber"));
        map.put("from", "rfid");
        sokect.onMessage(JSON.toJSONString(map));
        if (tagList.size() > 0) {
            if (requestType.equals("http")) {
                actionType = 99;
                HttpResponse response = httpClientUtil.HttoPost(map, "http://" + host + ":" + port + "/" + requestUrl);
                System.out.println(response.getStatusLine().getStatusCode());
            } else if (requestType.equals("socket")) {
//                System.out.println("通过判断进来了requestType为socket的方法");
                if (socketClient2 == null) {
                    System.out.println("socket客户端未启动");
                } else {
//                    System.out.println("发送socket="+JSON.toJSONString(map));
//                    System.out.println("socket客户端正常");
//                    System.out.println("消息发出去了");
                    socketClient2.SendThread(JSON.toJSONString(map));
                }
                SocketClientAct clientAct = new SocketClientAct(host, port);
//
            } else if (actionType == -1) {
                HttpResponse response = httpClientUtil.HttoPost(map, "http://" + utils.getKeyValue("serverIP") + ":" + utils.getKeyValue("serverPort") + "/DangD/getDataRecordByRfid");
                httpClientUtil.HttoPost(map, "http://" + utils.getKeyValue("serverIP") + ":" + utils.getKeyValue("serverPort") + "/DangD/getDataRecordByRfid");
                System.out.println(response.getStatusLine().getStatusCode());

            }
            if (actionType == 5) {
                if (requestType.equals("http")) {
                    httpClientUtil.HttoPost(map, "http://" + socketHost + ":" + socketProt + "/" + requestUrl);
                } else if (requestType.equals("socket")) {
                    SocketClientAct clientAct = new SocketClientAct(socketHost, socketProt);
                    clientAct.sendMessage(JSON.toJSONString(map));
                }
            }
            System.out.println(map);
        }
    }


}
